package com.coder520.sync_learning.demo.ThreadPool01;

import java.util.LinkedList;

public class LinkedRunnableQueue implements RunnaleQueue {
    //任务队列的最大容量，在构造的时候传入
    private final int limit;

    //如果队列中的任务已经满了，则需要执行拒绝的策略
    private final DenyPolicy denyPolicy;

    //存放任务的队列
    private final LinkedList<Runnable> runnableList=new LinkedList<>();

    private final ThreadPool threadPool;


    public LinkedRunnableQueue(int limit, DenyPolicy denyPolicy, ThreadPool threadPool) {
        this.limit = limit;
        this.denyPolicy = denyPolicy;
        this.threadPool = threadPool;
    }


    @Override
    public void offer(Runnable runnable) {
        synchronized (runnableList){
            if (runnableList.size()>=limit){
                //无法容纳新的任务时，进行拒绝的策略
                denyPolicy.reject(runnable,threadPool);
            }else{
                //将任务加入到队尾，并且唤醒阻塞中的线程
                runnableList.addLast(runnable);
                runnableList.notifyAll();
            }

        }
    }

    @Override
    public Runnable task() throws InterruptedException {
        synchronized (runnableList){
            while (runnableList.isEmpty()){
                try {
                    //如果任务队列中没有可执行的，当前的线程就会被挂起，进入runnablelist关联的monitor  waitset中等待唤醒（新的任务加入）
                    runnableList.wait();
                }catch (InterruptedException e){
                    //被中断的时候需要将这个异常进行抛出
                    throw e;
                }
            }
        }
        //从当先的任务队列中移除一个任务
        return runnableList.removeFirst();
    }

    @Override
    public int size() {
        synchronized (runnableList){
            //返回当前任务队列当中的队列数量
            return runnableList.size();
        }
    }
}
